<template>
  <CompOperate
    :field="field"
    :designer="designer"
    :design-state="designState"
    :parent-list="parentList"
    :parent-widget="parentWidget"
    :sub-form-row-id="subFormRowId"
    :sub-form-row-index="subFormRowIndex"
    :sub-form-col-index="subFormColIndex"
    :index-of-parent-list="indexOfParentList"
    :display-style="field.options.displayStyle"
  >
    <div class="scene-waiting-widget">
      <div class="list-inside">
        <div
          :style="getStyle('head')"
          class="header-area queue-item"
          v-if="optionsInfo.headShow"
        >
          <template v-for="item in optionsInfo.colOptions">
            <div
              class="item"
              :class="getClassName(item.value)"
              v-if="getColShow(item.value)"
              :style="setFlex(item, 'head')"
            >
              {{ item.label }}
            </div>
          </template>
        </div>
        <div class="list-area" :style="getStyle('list')" v-if="true">
          <template v-for="(item, index) in waitingPatientInfos">
            <div class="queue-item" :style="getStyle('listItem')">
              <template v-for="items in optionsInfo.colOptions">
                <template v-if="getColShow(items.value)">
                  <div
                    class="item"
                    :class="getClassName(items.value)"
                    :style="setFlex(items, 'list')"
                  >
                    <template
                      v-if="
                        items.value !== 'treatingPatient' &&
                        items.value !== 'waitPatientList'
                      "
                    >
                      <div
                        class="item-inside-default"
                        v-if="!!item[items.value]"
                        :class="{ 'item-inside': optionsInfo.itemShadow }"
                      >
                        <!--人数-->
                        <template v-if="items.value === 'waitPatientCount'">
                          <div class="scroll-item-inside">
                            {{ item[items.value] || "\u00a0" }}
                          </div>
                        </template>
                        <!--除了人数-->
                        <template v-else>
                          <div
                            :data-value="item[items.value]"
                            :class="`${items.value}-wrap-info`"
                          >
                            <ScrollX
                              :key="`${item[items.value]}-${index}}`"
                              :speed="
                                optionsInfo['listSpeed'] > 15
                                  ? 15
                                  : optionsInfo['listSpeed']
                              "
                            >
                              {{ getColContent(item, items.value) || "\u00a0" }}
                            </ScrollX>
                          </div>
                        </template>
                      </div>
                    </template>
                    <template v-if="items.value === 'treatingPatient'">
                      <span
                        class="treating-patient-area"
                        v-if="!!getCurrentPatient(item)"
                        :style="getStyle('currentPatient')"
                      >
                        <ScrollEditX
                          :content="getCurrentPatient(item) || '\u00a0'"
                          :key="`${item[items.value]}`"
                        />
                      </span>
                    </template>
                    <template v-if="items.value === 'waitPatientList'">
                      <template v-if="optionsInfo.openScroll">
                        <vue-seamless-scroll
                          :ref="`scroll-${item.workerId}`"
                          class="scroll"
                          :key="widgetKey"
                          @ScrollEnd="(e) => handleScrollEnd(e, item)"
                          :class-option="classOptionTips"
                          :data="item.waitPatientList"
                        >
                          <div
                            class="inside-content"
                            :class="{
                              patient_space: optionsInfo['patientSpace'],
                            }"
                          >
                            <span
                              class="patient"
                              :style="getStyle('waitItem')"
                              v-for="(item, index) in item.waitPatientList"
                              :key="`${item.queuingId || index}-${
                                item.patientIdNo || index
                              }`"
                              v-html="getWaitingContent(item)"
                            />
                          </div>
                        </vue-seamless-scroll>
                      </template>
                      <template v-else>
                        <div class="no-scroll">
                          <div class="inside-content" :class="getEllipsis">
                            <span
                              class="patient"
                              :style="getStyle('waitItem')"
                              v-for="(item, index) in item.waitPatientList"
                              :key="`${item.queuingId || index}-${
                                item.patientIdNo || index
                              }-${index}`"
                              v-html="getWaitingContent(item)"
                            />
                          </div>
                        </div>
                      </template>
                    </template>
                  </div>
                </template>
              </template>
            </div>
          </template>
        </div>
      </div>
    </div>
  </CompOperate>
</template>

<script>
import { NoticeBar } from "vant";
import { v4 as uuid } from "uuid";
import { pxToVw, remToPx } from "@/utils/common";
import emitter from "@/utils/designer/emitter";
import vueSeamlessScroll from "vue-seamless-scroll";
import CompOperate from "@c/public/form-designer/devType/modules/compOperate.vue";
import mixin from "@sc/templateDetails/modules/homeMiddle/fieldMixin";
import ScrollX from "@c/public/seamlessScroll/ScrollX.vue";
import ScrollEditX from "@c/public/seamlessScroll/ScrollEditX.vue";
import { buildParentApi } from "@/utils/designer/util";
import NoticeBarInfo from "@c/public/noticeBar/index.vue";
import SeamlessScroll from "@c/public/seamlessScroll/index2.vue";
import Marquee from "@c/public/seamlessScroll/marquee.vue";
import ScrollToRate from "@c/public/seamlessScroll/ScrollToRate.vue";

let buildParent = buildParentApi();
export default {
  name: "scene-waiting-widget",

  componentName: "FieldWidget", //必须固定为FieldWidget，用于接收父级组件的broadcast事件

  mixins: [emitter, mixin],

  components: {
    NoticeBarInfo,
    ScrollX,
    CompOperate,
    ScrollEditX,
    NoticeBar,
    vueSeamlessScroll,
    SeamlessScroll,
    Marquee,
    ScrollToRate,
  },

  props: {
    widget: Object,
    field: Object,
    parentWidget: Object,
    parentList: Array,
    indexOfParentList: Number,
    designer: Object,
    designState: {
      type: Boolean,
      default: false,
    },
    devType: {
      type: Boolean,
      default: false,
    },

    subFormRowIndex: {
      /* 子表单组件行索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormColIndex: {
      /* 子表单组件列索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormRowId: {
      /* 子表单组件行Id，唯一id且不可变 */ type: String,
      default: "",
    },

    headTitle: {
      type: String,
      default: "",
    },
    visibleTitle: {
      type: Boolean,
    },
    //prop传入的表单JSON配置
    parentApi: {
      type: Object,
      default: () => buildParentApi(),
    },
  },

  data() {
    return {
      widgetKey: uuid(),
      optionsInfo: Object(),
    };
  },

  computed: {
    //生成唯一的字符串
    getOnlyId() {
      return function () {
        return uuid();
      };
    },

    // 滚动的设置项目
    getScrollOptions() {
      const self = this;
      let infos = self.optionsInfo || Array();
      return function (info) {
        let speedInfo = info.speed > 30 ? 30 : info.speed;
        let speedRem = parseInt(remToPx(speedInfo));
        return {
          text: `${info}`, // 通知内容
          fontSize: infos?.itemFontSize, // 通知内容文字大小（默认16px）
          fontWeight: infos?.itemFontWeight,
          color: infos?.listFontColor, // 通知内容文字颜色(默认#f60)
          delay: "1000", // 动画延迟时间(默认一秒后开始滚动，单位毫秒)
          speed: speedRem, // 滚动速率默认50 (px/s)
          scrollable: info.length > 7,
          position: "center",
        };
      };
    },

    // 温馨提示的滚动
    classOptionTips() {
      let { openScroll, waitingNumber, waitingVisitStep } =
        this.field.options.waitingInfoConfig;
      return {
        step: [1, 1.5, 2, 2.5, 3][waitingVisitStep - 1], // 数值越大速度滚动越快
        hoverStop: true,
        limitMoveNum: openScroll ? waitingNumber : 999999, // 开始无缝滚动的数据量 this.dataList.length
        direction: 2, // 0向下 1向上 2向左 3向右
        isSingleRemUnit: true,
      };
    },

    // 栏目是否显示
    getColShow() {
      return function (val) {
        const self = this;
        let { defaultShowCol, mergeColInfo } = self.optionsInfo || Array();
        if (val === "registerObjNames") {
          if (
            !!mergeColInfo &&
            !!mergeColInfo[1] &&
            !!mergeColInfo[1].length &&
            mergeColInfo[1].length === 2
          ) {
            return false;
          } else {
            return defaultShowCol.includes(val);
          }
        } else {
          return defaultShowCol.includes(val);
        }
      };
    },

    // 获候诊的患者
    getWaitingContent() {
      return function (item) {
        const self = this;
        let { patientOrderNo } = self.optionsInfo || Array();
        let orderNo = item?.orderNo;
        let patientOrderNoInfo = "";
        if (!!orderNo) {
          patientOrderNoInfo = `<span class="${
            patientOrderNo ? "patient-orderNo" : "patient-orderNo2"
          }">${item.orderNo || "\u00a0"}</span>`;
        }
        let temp = `${patientOrderNoInfo} ${item.patientName || "\u00a0"}`;
        return this.$lodash.trim(temp);
      };
    },

    // 拼接显示具体内容
    getColContent() {
      return function (val, key) {
        const self = this;
        let { mergeColInfo, registerObjNameKey, roomNameKey, deptNameKey } =
          self.optionsInfo || Object();
        switch (key) {
          // 诊室&诊室简称
          case "treatmentRoomName":
            if (
              !!mergeColInfo &&
              !!mergeColInfo[1] &&
              !!mergeColInfo[1].length &&
              mergeColInfo[1].length === 2
            ) {
              let mergeInfo = `${val[roomNameKey] || val[key] || "\u00a0"} ${
                val[registerObjNameKey] || "\u00a0"
              }`;
              return self.$lodash.trim(mergeInfo);
            } else {
              return val[roomNameKey] || val[key] || "\u00a0";
            }
          case "registerObjNames":
            return val[registerObjNameKey] || val[key];
          case "deptName":
            return val[deptNameKey] || val[key];
          default:
            return val[key] || "\u00a0";
        }
      };
    },

    // 患者的ClassName
    getClassName() {
      return function (val) {
        switch (val) {
          case "treatingPatient":
            return "current-patient";
          case "waitPatientList":
            return "wait-patient";
          case "waitPatientCount":
            return "patient-count";
          case "registerObjNames":
            return "register-name";
          case "deptName":
            return "deptName-name";
          case "treatmentRoomName":
            return "treatment-room-name";
        }
      };
    },

    // 模板的行内样式
    getStyle() {
      return function (val) {
        const self = this;
        let info = self.optionsInfo || Array();
        let Obj = Object();
        let { showRowNums } = this.optionsInfo;
        switch (val) {
          case "head":
            Reflect.set(Obj, "color", info.headerFontColor);
            Reflect.set(Obj, "fontSize", pxToVw(info.headFontSize));
            Reflect.set(Obj, "fontWeight", info.headFontWeight);
            Reflect.set(Obj, "backgroundColor", info.headerBackgroundColor);
            return Obj;
          case "list":
            Reflect.set(Obj, "height", pxToVw(info.contentHeight));
            return Obj;
          case "waitItem":
            Reflect.set(Obj, "minWidth", pxToVw(info.waitPatientWidth));
            return Obj;

          case "listItem":
            Reflect.set(
              Obj,
              "border-bottom-width",
              pxToVw(info.itemBorderBottom)
            );
            Reflect.set(
              Obj,
              "height",
              pxToVw(info.contentHeight / showRowNums)
            );
            Reflect.set(
              Obj,
              "border-bottom-color",
              info?.itemBorderColor || "rgba(170, 170, 170, 0.75)"
            );
            return Obj;
          case "currentPatient":
            Reflect.set(
              Obj,
              "background",
              info?.itemBackground || "rgba(0, 89, 179, 0.2)"
            );
            return Obj;
          case "itemBackground":
            if (info?.itemShadow) {
              Reflect.set(
                Obj,
                "background",
                info?.itemBackground || "rgba(0, 89, 179, 0.2)"
              );
            } else {
              Reflect.deleteProperty(Obj, "background");
            }
            return Obj;
        }
      };
    },

    // 设置宽度和字号
    setFlex() {
      return function (item, val) {
        const self = this;
        let info = self.optionsInfo || Array();
        let Obj = Object();
        switch (val) {
          case "head":
            Reflect.set(Obj, "flex", item.flex || 1);
            Reflect.set(Obj, "fontWeight", info.headFontWeight);
            Reflect.set(Obj, "fontSize", pxToVw(info.headFontSize));
            return Obj;
          case "list":
            Reflect.set(Obj, "flex", item.flex || 1);
            Reflect.set(Obj, "fontWeight", info.itemFontWeight);
            Reflect.set(Obj, "fontSize", pxToVw(info.itemFontSize));
            return Obj;
        }
      };
    },

    // 当前就诊的患者|| 医生暂停接诊
    getCurrentPatient() {
      return function (val) {
        /**
         * 在线状态 0在线 1暂停 2退出
         **/
        const self = this;
        let { patientOrderNo } = self.optionsInfo || Array();
        let type = parseInt(val.onlineStatus);
        switch (type) {
          case 0:
          case 2:
            if (!!val.treatingPatient && !!val.treatingPatient.length) {
              let currentPatient = Array();
              val.treatingPatient.forEach((item) => {
                let orderNo = item?.orderNo;
                let patientOrderNoInfo = "";
                if (!!orderNo) {
                  patientOrderNoInfo = `<span class="${
                    patientOrderNo ? "patient-orderNo" : "patient-orderNo2"
                  }">${item.orderNo || "\u00a0"}</span>`;
                }
                let temp = `${patientOrderNoInfo} ${
                  item.patientName || "\u00a0"
                }`;
                currentPatient.push(temp);
              });
              return this.$lodash.join(currentPatient, " ");
            } else {
              return "\u00a0";
            }
          case 1:
            return "暂停接诊";
        }
      };
    },

    // 列表的队列的患者
    waitingPatientInfos() {
      let devType = this.devType;
      let { showRowNums } = this.field.options.waitingInfoConfig;
      let queuePatientList = this.$store.getters["getWaitingPatientInfo"];
      let listInfo = devType
        ? queuePatientList.apiData
        : queuePatientList.mockData;
      if (listInfo.length > showRowNums) {
        return listInfo.slice(0, showRowNums);
      } else {
        let arr = new Array(showRowNums - listInfo.length).fill({});
        return [...listInfo, ...arr];
      }
    },

    // 是否显示省略号
    getEllipsis() {
      const self = this;
      let { ellipsisState } = self.optionsInfo;
      if (ellipsisState) {
        return "ellipsis";
      }
    },

    // 无内容区域背景色是否显示
    contentTrim() {
      return function (val) {
        let content = this.getCurrentPatient(val);
        return !!this.$lodash.trim(content);
      };
    },
  },

  mounted() {
    this.handleOnMounted();
  },

  methods: {
    // 等待候诊滚动结束
    handleScrollEnd(e, row) {
      const self = this;
      if (self.$refs[`scroll-${row.workerId}`]) {
        self.$nextTick(() => {
          self.$refs[`scroll-${row.workerId}`][0] &&
            self.$refs[`scroll-${row.workerId}`][0].reset();
        });
      }
    },

    // 接收父组件传递过来的数据
    async executeMethod(key, data) {
      switch (key) {
        case "patientListInfo":
          console.log(`患者列表-数据处理逻辑-${data}`);
          // this.widgetKey = uuid();
          let patientList = this.$lodash.cloneDeep(data);
          // buildParent.executeParentMethod('writeLog', JSON.stringify({sign: '模板-患者信息', key: key, data: data}));
          await this.$store.dispatch("setWaitingPatientInfo", patientList);
          break;
      }
    },
  },

  watch: {
    field: {
      handler: function (val) {
        this.widgetKey = uuid();
        let key = val.options.config;
        this.optionsInfo = val.options[key];
      },
      deep: true,
      immediate: true,
    },
  },

  destroyed() {
    this.unregisterFromRefList();
  },
};
</script>

<style lang="scss" scoped>
.scene-waiting-widget {
  background-color: transparent;
  color: #333;
  align-self: center;
  align-items: center;
  display: flex;
  flex-direction: column;
  height: 100%;
  line-height: 100%;
  box-sizing: border-box;
  margin: 20px 28px 10px 28px;
  overflow: hidden;

  .list-inside {
    border-radius: 20px !important;
    width: 100%;
    overflow: hidden;
    border: 1px rgba(170, 170, 170, 0.75) solid !important;

    .header-area {
      width: 100%;
      display: flex;
      background-color: #0059b3;
      color: #fff;
      height: 100px;
      border: none !important;

      .queue-item .item {
        height: initial;
      }

      .wait-patient {
        display: inline !important;
        align-self: center;
        align-items: center;
        text-align: center;
      }
    }

    .list-area {
      width: 100%;
      display: flex;
      height: auto;
      background: white;
      flex-direction: column;
      overflow: hidden;

      .queue-item .item {
        height: 94%;
      }

      .item {
        color: #000000;
      }

      .treatmentRoomName-wrap-info {
        display: flex;
        height: 100%;
        min-width: 100%;
        overflow: hidden;
      }
    }

    .queue-item {
      display: flex;
      width: 100%;
      align-items: center;
      align-self: center;
      flex-direction: unset;
      border-bottom: 1px rgba(170, 170, 170, 0.75) solid;
      flex-grow: 1;
      overflow: hidden;

      &:last-child {
        border-bottom: none;
      }

      .item {
        display: flex;
        flex: 1;
        align-self: center;
        align-items: center;
        align-content: center;
        justify-content: center;
        flex-wrap: nowrap;
        white-space: nowrap;
        overflow: hidden;
        line-height: normal;

        .scrollText {
          height: 100%;
          width: 100%;
          display: flex;
          justify-content: left;
          align-items: center;
          align-self: center;
        }

        .scroll-item-inside {
          color: #000000;
          padding-right: 14px;
        }

        .item-inside-default {
          display: flex;
          height: 100%;
          width: 100%;
          justify-content: left;

          > div {
            display: flex;
            width: 100% !important;
            overflow: hidden;
          }
        }
      }

      .deptName-name,
      .patient-count {
        .item-inside-default {
          display: inline-flex;
          align-items: center;
          align-self: center;
          justify-content: center;
          line-height: normal;
          flex-shrink: 0;
          border-radius: 10px;
          padding: 2px 10px;
          color: #333333;
          width: calc(100% - 10px - 10px);
          max-width: calc(100% - 10px - 10px);
          box-sizing: border-box;
          height: calc(84%);

          div {
            display: flex;
            flex-basis: 100%;
            align-self: center;
            justify-content: center;
          }
        }

        .item-inside {
          background: rgba(0, 89, 179, 0.2);
        }
      }

      .treatment-room-name {
        .item-inside {
          background: transparent !important;
        }
      }

      .current-patient {
        flex: 1.5;

        :deep(.treating-patient-area) {
          .patient-orderNo {
            padding: 2px 12px;
            display: inline-flex;
            text-align: center;
            justify-content: center;
            min-width: 60px;
            background: rgba(68, 130, 192, 1);
            border-radius: 12px;
            overflow: hidden;
            color: white;
          }
        }

        span {
          display: flex;
          line-height: normal;
          align-items: center;
          align-self: center;
          background: rgba(0, 89, 179, 0.2);
          border-radius: 10px;
          padding: 2px 10px;
          color: #333333;
          @include singleEllipsis(260px);
          width: calc(100% - 10px - 10px);
          max-width: calc(100% - 10px - 10px);
          box-sizing: border-box;
          height: calc(84%);
        }
      }

      .wait-patient {
        flex: 3;
        padding-right: 8px;
        justify-content: flex-start;

        :deep(.scroll) {
          width: 100%;
          height: 80px;
          overflow: hidden;

          > div {
            height: 100%;
            overflow: hidden;

            > div {
              height: 100%;
            }
          }

          .inside-content {
            height: 100%;
            display: flex;
            align-self: center;
            align-items: center;
            overflow: hidden;

            .patient {
              height: auto;
              align-self: center;
              align-items: center;
              line-height: inherit;
              overflow: hidden;
              padding-right: 20px;

              .patient-orderNo {
                padding: 2px 12px;
                display: inline-flex;
                //height: 60px;
                text-align: center;
                justify-content: center;
                //line-height: 60px;
                background: rgba(68, 130, 192, 1);
                border-radius: 12px;
                min-width: 60px;
                overflow: hidden;
                color: white;
              }
            }
          }

          .patient_space {
            margin-right: 240px;
          }
        }

        .no-scroll {
          padding-right: 20px;
          overflow: hidden;

          .inside-content {
            height: 100%;
            display: flex;
            align-self: flex-start;
            align-items: flex-start;
            overflow: hidden;
            text-align: left;

            .patient {
              height: auto;
              align-self: center;
              align-items: center;
              line-height: inherit;
              flex-basis: auto;
              padding-right: 20px;

              :deep(.patient-orderNo) {
                padding: 2px 12px;
                display: inline-flex;
                //height: 60px;
                text-align: center;
                justify-content: center;
                //line-height: 60px;
                background: rgba(68, 130, 192, 1);
                border-radius: 12px;
                min-width: 60px;
                overflow: hidden;
                color: white;
              }
            }
          }

          .ellipsis {
            @include singleEllipsis(100%);
            display: block;
          }
        }
      }

      .patient-count {
        flex: 0.8;

        .item-inside {
          @include fontWeight();
        }

        .scroll-item-inside {
          padding-right: 0;
        }
      }

      .register-name {
        flex: 1.5;
      }

      .waiting-info {
        @include singleEllipsis(100%);
      }
    }
  }
}
</style>